package com.system;

import android.opengl.GLES20;
import android.opengl.GLES30;
import android.opengl.GLES32;
import android.opengl.GLUtils;

import java.io.IOException;

/**
 * @Author: clm
 * @Date: 2018-10-27
 */

public class Shader {
    public int mShaderProgram;

    /**
     * 返回构建的shader指针,如果错误,返回-1
     * @param shaderType
     * @param sourceFileName
     */
    public int getShader(int shaderType, final String sourceFileName){
        //为了兼容,使用GLES32
        int shaderLoc = GLES32.glCreateShader(shaderType);
        try{
            String source = FileUtils.getFromAssets(sourceFileName);
            GLES32.glShaderSource(shaderLoc, source);
            GLES32.glCompileShader(shaderLoc);
            int error[] = new int[1];
            GLES32.glGetShaderiv(shaderLoc, GLES32.GL_COMPILE_STATUS, error, 0);
            if (error[0] == GLES32.GL_FALSE) {
                String shaderTypeStr = "";
                switch (shaderType){
                    case GLES32.GL_VERTEX_SHADER:
                        shaderTypeStr = "vs";
                        break;
                    case GLES32.GL_GEOMETRY_SHADER:
                        shaderTypeStr = "gs";
                        break;
                    case GLES32.GL_FRAGMENT_SHADER:
                        shaderTypeStr = "fs";
                        break;
                }
                GLLog.loge(shaderTypeStr + "编译异常,文件名[" + sourceFileName + "],异常原因:" + GLES30.glGetShaderInfoLog(shaderLoc));
                return -1;
            }
        }
        catch (Exception e){
            e.printStackTrace();
            return -1;
        }
        return shaderLoc;
    }
    public Shader(String vsSourceFilename, String gsSourceFilename, String fsSourceFilename){
        int vs = getShader(GLES30.GL_VERTEX_SHADER, vsSourceFilename);
        int gs = getShader(GLES32.GL_GEOMETRY_SHADER, gsSourceFilename);
        int fs = getShader(GLES30.GL_FRAGMENT_SHADER, fsSourceFilename);
        if(vs != -1 && gs != -1 && fs != -1){
            mShaderProgram = GLES30.glCreateProgram();
            GLES30.glAttachShader(mShaderProgram, vs);
            GLES30.glAttachShader(mShaderProgram, gs);
            GLES30.glAttachShader(mShaderProgram, fs);
            GLES30.glLinkProgram(mShaderProgram);
            int error[] = new int[1];
            GLES30.glGetProgramiv(mShaderProgram, GLES30.GL_LINK_STATUS, error, 0);
            if(error[0] == GLES30.GL_FALSE){
                String msg = GLES30.glGetProgramInfoLog(mShaderProgram);
                GLLog.loge("链接着色器异常:" + msg);
                return;
            }
        }
    }
    public Shader(String vsSourceFilename, String fsSourceFilename){
        int vs = getShader(GLES30.GL_VERTEX_SHADER, vsSourceFilename);
        int fs = getShader(GLES30.GL_FRAGMENT_SHADER, fsSourceFilename);
        if(vs != -1 && fs != -1){
            mShaderProgram = GLES30.glCreateProgram();
            GLES30.glAttachShader(mShaderProgram, vs);
            GLES30.glAttachShader(mShaderProgram, fs);
            GLES30.glLinkProgram(mShaderProgram);
            int error[] = new int[1];
            GLES30.glGetProgramiv(mShaderProgram, GLES30.GL_LINK_STATUS, error, 0);
            if(error[0] == GLES30.GL_FALSE){
                String msg = GLES30.glGetProgramInfoLog(mShaderProgram);
                GLLog.loge("链接着色器异常:" + msg);
                return;
            }
        }
    }
//    public Shader(String vsSourceFilename, String fsSourceFilename){
//        int vs = GLES30.glCreateShader(GLES30.GL_VERTEX_SHADER);
//        int fs = GLES30.glCreateShader(GLES30.GL_FRAGMENT_SHADER);
//        try {
//            String vsSource = FileUtils.getFromAssets(vsSourceFilename);
//            String fsSource = FileUtils.getFromAssets(fsSourceFilename);
//            if(GLLog.S_DEBUG){
//                GLLog.loge("vsSource : \n" + vsSource);
//                GLLog.loge("fsSource : \n" + fsSource);
//            }
//            GLES30.glShaderSource(vs, vsSource);
//            GLES30.glShaderSource(fs, fsSource);
//            GLES30.glCompileShader(vs);
//            int error[] = new int[1];
//            GLES30.glGetShaderiv(vs, GLES30.GL_COMPILE_STATUS, error, 0);
//            if(error[0] == GLES30.GL_FALSE){
//                GLLog.loge("vs编译异常:" + GLES30.glGetShaderInfoLog(vs));
//            }
//            else{
//                GLLog.loge("vs编译正常");
//            }
//            GLES30.glCompileShader(fs);
//            GLES30.glGetShaderiv(fs, GLES30.GL_COMPILE_STATUS, error, 0);
//            if(error[0] == GLES30.GL_FALSE){
//                GLLog.loge("fs编译异常:" + GLES30.glGetShaderInfoLog(fs));
//            }
//            else{
//                GLLog.loge("fs编译正常");
//            }
//            mShaderProgram = GLES30.glCreateProgram();
//            GLES30.glAttachShader(mShaderProgram, vs);
//            GLES30.glAttachShader(mShaderProgram, fs);
//            GLES30.glLinkProgram(mShaderProgram);
//            GLES30.glDeleteShader(vs);
//            GLES30.glDeleteShader(fs);
//            error[0] = GLES30.GL_TRUE;
//            GLES30.glGetProgramiv(mShaderProgram, GLES30.GL_LINK_STATUS, error, 0);
//            if(error[0] == GLES30.GL_FALSE){
//                String msg = GLES30.glGetProgramInfoLog(mShaderProgram);
//                GLLog.loge("链接着色器异常:" + msg);
//                return;
//            }
//            else{
//                GLLog.loge("链接着色器正常");
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//            GLLog.loge("加载着色器文件异常:" + e.getMessage());
//        }
//    }
}
